﻿const { app, BrowserWindow, screen, ipcMain, Menu } = require("electron");
const path = require("path");
const fs = require("fs");
const mqtt = require("mqtt");
const S7 = require("./drivers/s7.js");
const SICKRFU = require("./drivers/sickrfu630.js");
const inspector = require('inspector');
// const CAM = require("./drivers/cam.js");
const Carousel = require("./Carousel.js");
const { Worker } = require('worker_threads');

// 创建Worker线程
const logWorker = new Worker('./logworker.js');

// 处理Worker的消息
logWorker.on('message', (result) => {
  if (!result.success) {
    console.error('Failed to log text:', result.error);
  }
});

class StatusManager {
  constructor(deviceId, mqttClient) {
    this.deviceId = deviceId;
    this.mqttClient = mqttClient;
    this.status = {
      cam: '',
      plc: '',
      rfid: '',
      mqtt: ''
    };
    for (const device in this.status) {
      this.updateStatus(device,'connecting');
    }
  }

  updateStatus(device, status) {
    if (this.status[device] !== status) {
      const oldStatus = this.status[device];
      this.status[device] = status;
      this.publishStatus();
      // 只在状态变化时输出日志
      const timestamp = new Date().toLocaleTimeString('zh-CN', { 
        hour12: false, 
        hour: '2-digit', 
        minute: '2-digit', 
        second: '2-digit' 
      });
      console.log(`[${timestamp}] ${device.toUpperCase()}: ${oldStatus} => ${status}`);
    }
  }

  publishStatus() {
    const status = this.status;
    status.app = 'connected';
    this.mqttClient.publish(
      `device/status/${this.deviceId}`,
      JSON.stringify(status),
      { qos: 1 }
    );
  }
}

const options = require('./options.json');

let mainWindow;
let carousel;
let mqttClient;
let statusManager;

/**
 * 加载配置
 * @returns {void}
 */
async function loadConfig(url) {
  const retryDelay = 30000; // 30秒重试间隔
  
  while (true) {
    try {
      const configManager = require('./config.js');
      const config = await configManager.loadConfig(url);
      configManager.validateConfig(config);
      configloaded(JSON.stringify(config));
      return;
    } catch (error) {
      console.error("Configuration error:", error.message);
      
      if (error.isLoadError) {
        // 加载错误，等待后重试
        console.log(`Retrying in ${retryDelay/1000} seconds...`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      } else {
        // 验证错误，直接退出
        console.error("Configuration validation failed, exiting...");
        process.exit(1);
      }
    }
  }
}

async function configloaded(data) {
  const config = JSON.parse(data);
  // console.log(config);
  // 初始化MQTT客户端
  mqttClient = mqtt.connect(options.mqtt.address, {
    clientId: `${config.id}`,
    clean: true,
    connectTimeout: 30000,
    username: options.mqtt.username,
    password: options.mqtt.password,
    reconnectPeriod: 5000,
    will: {
      topic: `device/status/${config.id}`,
      payload: JSON.stringify({app:'disconnected'}),
      qos: 1,
      retain: true
    }
  });

  // 添加MQTT错误处理
  mqttClient.on('error', (error) => {
    // console.error('MQTT connection error:', error);
    // Add reconnection logic
    mqttClient.connected = false;
    // console.log('Attempting to reconnect MQTT...');
    statusManager.updateStatus('mqtt', 'connecting');
    mqttClient.reconnect();
    
  });

  // 初始化状态管理器
  statusManager = new StatusManager(config.id, mqttClient);

  // MQTT连接成功时发送connected消息
  mqttClient.on('connect', () => {
    statusManager.updateStatus('mqtt', 'connected');
  });

  mqttClient.on('close', () => {
    statusManager.updateStatus('mqtt', 'connecting');
  });
  
  // camara = new CAM(
  //   photoPath=options.photo.path,
  //   photoUrl=options.photo.url
  // );

  carousel = new Carousel(config);

  const rfid = new SICKRFU(config.rfid[0].ip, config.rfid[0].port);
  rfid.on("data", (data) => {
    carousel.rfid.newData(data);
  });

  // RFID连接状态监控
  rfid.on('connected', () => {
    statusManager.updateStatus('rfid', 'connected');
  });

  rfid.on('reconnect', () => {
    statusManager.updateStatus('rfid', 'connecting');
  });

  // 初始化PLC
  const plc = new S7(config.plc,102,config.totalplates);
  let lastPointerTime = Date.now();
  plc.on("newpointer", (data) => {
    const currentTime = Date.now();
    const interval = currentTime - lastPointerTime;
    lastPointerTime = currentTime;
    if (interval > 200) {
      console.log("Pointer interval: " + interval + "ms");
    };
    result = carousel.newPointer(data);
    const resultjson = JSON.stringify(result);
    mainWindow.webContents.send("newpointer", resultjson);
    // logWorker.postMessage(carousel.log.text);
    // logWorker.postMessage(JSON.stringify(data));
  });

  // PLC连接状态监控
  plc.on('connected', () => {
    statusManager.updateStatus('plc', 'connected');
  });

  plc.on('reconnect', () => {
    statusManager.updateStatus('plc', 'disconnected');
  });
  mainWindow.webContents.on("did-finish-load", () => {
    console.log("Page loading completed");
    mainWindow.webContents.send("config", JSON.stringify(config));
    if (options.mode === 'debug') {
      mainWindow.webContents.openDevTools({ mode: 'detach' }); // 在页面加载完成后打开开发者工具
    }
  });
}

function createWindow() {
  Menu.setApplicationMenu(null);
  mainWindow = new BrowserWindow({
    width: screen.getPrimaryDisplay().workAreaSize.width,
    height: screen.getPrimaryDisplay().workAreaSize.height,
    fullscreenable: true,
    frame: false,
    transparent: false,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: path.join(__dirname, "preload.js"),
      zoomFactor: 1.0,
      spellcheck: false,
      enableWebSQL: false,
      devTools: true
    },
  });

  // 禁用窗口的缩放功能
  mainWindow.webContents.setVisualZoomLevelLimits(1, 1);
  mainWindow.webContents.setZoomFactor(1);
  // 禁用手势缩放
  mainWindow.webContents.on('zoom-changed', (event) => {
    event.preventDefault();
  });
  
  // 全屏模式
  mainWindow.loadFile("index.html");
  loadConfig(options.configurloptions);
}

// 添加全局错误处理
process.on("uncaughtException", (error) => {
  console.error("Uncaught Exception:", error);
});

// 添加窗口错误处理
app.on("render-process-gone", (event, webContents, details) => {
  console.error("Render process gone:", details);
});

// // 监听调试客户端连接状态
// inspector.open(9229, '0.0.0.0', true);
// inspector.console.log = console.log;

// inspector.Session.prototype.postAsync = function(...args) {
//   return new Promise((resolve, reject) => {
//     try {
//       this.post(...args, (err, result) => {
//         if (err) reject(err);
//         else resolve(result);
//       });
//     } catch (error) {
//       reject(error);
//     }
//   });
// };

let debuggerConnected = true;
// const session = new inspector.Session();
// session.connect();

// session.on('inspectorNotification', (message) => {
//   if (message.method === 'Runtime.executionContextCreated') {
//     if (!debuggerConnected) {
//       debuggerConnected = true;
//       log('调试客户端已连接');
//     }
//   }
// });

// // 定期检查连接状态
// setInterval(async () => {
//   try {
//     await session.postAsync('Runtime.evaluate', { expression: '1 + 1' });
//     if (!debuggerConnected) {
//       debuggerConnected = true;
//       log('调试客户端已连接');
//     }
//   } catch (error) {
//     if (debuggerConnected) {
//       // debuggerConnected = false;
//       log('调试客户端已断开');
//     }
//   }
// }, 2000);

// 添加启动日志
app
  .whenReady()
  .then(() => {
    createWindow();
    console.log("App is ready");
  })
  .catch((err) => {
    console.error("Failed to start app:", err);
  });
function log(message) {
  const now = new Date();
  const timestamp = `${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}-${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}.${String(now.getMilliseconds()).padStart(1, '0')}`;
  console.log(`[${timestamp}]:${message}`);
  // 发送消息到Worker进行日志存储
  logWorker.postMessage({ text: `[${timestamp}]:${message}` });
}

// 应用退出时清理MQTT连接
app.on('window-all-closed', () => {
  if (mqttClient) {
    mqttClient.end();
  }
  if (process.platform !== 'darwin') {
    app.quit();
  }
});